﻿namespace PauloMorgado.SharePoint.Services.Lists
{
    using System;
    using System.Collections.Generic;
    using System.Net;
    using System.ServiceModel;
    using System.Xml.Linq;
    using String = PauloMorgado.SharePoint.String;

    internal static class ListsService
    {
        public static IListsService CreateListsChannel(EndpointAddress endpointAddress, HttpClientCredentialType credentialType, NetworkCredential credential)
        {
            return ServiceHelper.CreateChannelFactory<IListsService>(endpointAddress, credentialType, credential).CreateChannel();
        }

        public static IListsService CreateListsChannel(Uri baseUri, HttpClientCredentialType credentialType, NetworkCredential credential)
        {
            return ListsService.CreateListsChannelFactory(baseUri, credentialType, credential).CreateChannel();
        }

        public static ChannelFactory<IListsService> CreateListsChannelFactory(Uri baseUri, HttpClientCredentialType credentialType, NetworkCredential credential)
        {
            return ServiceHelper.CreateChannelFactory<IListsService>(baseUri, "_vti_bin/Lists.asmx", credentialType, credential);
        }

        public static IEnumerable<XElement> GetAllListItems(this IListsService listsService, GetListItemsRequest getListItemsRequest)
        {
            getListItemsRequest = getListItemsRequest ?? new GetListItemsRequest();
            getListItemsRequest.Body = getListItemsRequest.Body ?? new GetListItemsRequestBody();

            if (getListItemsRequest.Body.queryOptions == null)
            {
                getListItemsRequest.Body.queryOptions = new XElement("{http://schemas.microsoft.com/sharepoint/soap/}QueryOptions");
            }

            XElement pagingElement = null;
            if (getListItemsRequest.Body.queryOptions.Element("{http://schemas.microsoft.com/sharepoint/soap/}Paging") != null)
            {
                pagingElement = getListItemsRequest.Body.queryOptions.Element("{http://schemas.microsoft.com/sharepoint/soap/}Paging");
            }
            else
            {
                pagingElement = new XElement("{http://schemas.microsoft.com/sharepoint/soap/}Paging");
                getListItemsRequest.Body.queryOptions.Add(pagingElement);
            }

            XAttribute listItemCollectionPositionNextAttribute = null;
            if (pagingElement.Attribute("ListItemCollectionPositionNext") != null)
            {
                listItemCollectionPositionNextAttribute = pagingElement.Attribute("ListItemCollectionPositionNext");
            }
            else
            {
                listItemCollectionPositionNextAttribute = new XAttribute("ListItemCollectionPositionNext", "Paged=FALSE");
                pagingElement.Add(listItemCollectionPositionNextAttribute);
            }

            do
            {
                var getListItemsResponse = listsService.GetListItems(getListItemsRequest);

                foreach (var row in getListItemsResponse.Body.GetListItemsResult.Descendants("{#RowsetSchema}row"))
                {
                    yield return row;
                }

                var listItemCollectionPositionNextResponseAttribute = getListItemsResponse.Body.GetListItemsResult
                    .Element("{urn:schemas-microsoft-com:rowset}data").Attribute("ListItemCollectionPositionNext");

                listItemCollectionPositionNextAttribute.Value = listItemCollectionPositionNextResponseAttribute == null
                    ? string.Empty
                    : listItemCollectionPositionNextResponseAttribute.Value;

            } while (!String.IsNullOrWhiteSpace(listItemCollectionPositionNextAttribute.Value));
        }
    }
}
